﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using CoolERP_Entities;
using CoolERP_DAL;

namespace CoolERP_BLL
{
    public class BaseBLL<T> : IDisposable
    {
        public IDAL<T> dal { get; set; }
        public IUnitOfWork context { get; set; }
        public Type _type { get; set; }

        public BaseBLL()
        {
            context = new ErpEntities();
            //通过反射实例化
            string className = typeof(T).FullName;
            string dalNameSpace = className.Substring(0, className.IndexOf('_')) + "_DAL";
            string dalClassName = string.Format("{0}.{1}DAL", dalNameSpace, className.Substring(className.LastIndexOf('.') + 1));
            _type = Assembly.Load(dalNameSpace).GetType(dalClassName);
            object[] objs = new object[1] { context };
            dal = Activator.CreateInstance(_type, objs) as IDAL<T>;
        }

        #region======base method======
        public virtual bool Insert(T entity)
        {
            return dal.Insert(entity);
        }

        public virtual bool Inserts(List<T> items)
        {
            return dal.Inserts(items);
        }

        public virtual bool Delete(T entity)
        {
            return dal.Delete(entity);
        }

        public virtual bool Deletes(string key, string ids)
        {
            return dal.Deletes(key, ids);
        }

        public virtual bool Deletes(IList<T> items)
        {
            return dal.Deletes(items);
        }

        public virtual bool Update(T entity)
        {
            return dal.Update(entity);
        }

        public virtual bool Updates(List<T> items)
        {
            return dal.Updates(items);
        }

        public virtual bool Update<TEntity>(T entity, IList<TEntity> delMXB)
        {
            return dal.Update<TEntity>(entity, delMXB);
        }

        public virtual bool IsExist(Func<T, bool> exp)
        {
            return dal.IsExist(exp);
        }

        public virtual int SaveEntity(T entity, Func<T, bool> exp)
        {
            return dal.SaveEntity(entity, exp);
        }

        /// <summary>
        /// 不加载外键关联对象
        /// </summary>
        public virtual T GetEntity(Func<T, bool> exp)
        {
            return dal.GetEntity(exp);
        }

        /// <summary>
        /// 加载外键关联对象
        /// </summary>
        public virtual T GetModel(Func<T, bool> exp)
        {
            return dal.GetModel(exp);
        }

        public virtual List<T> GetList(Func<T, bool> exp)
        {
            return dal.GetList(exp).ToList();
        }

        public virtual List<T> GetList(Func<T, bool> exp, string orderExpr)
        {
            return dal.GetList(exp, orderExpr, 0).ToList();
        }

        public virtual List<T> GetList(Func<T, bool> exp, string orderExpr, int takeCount)
        {
            return dal.GetList(exp, orderExpr, takeCount).ToList();
        }

        public virtual List<T> GetPagerList(Func<T, bool> exp, string orderExpr, int? pageIndex, int pageSize, out int totalCount)
        {
            return dal.GetPagerList(exp, orderExpr, pageIndex, pageSize, out totalCount).ToList();
        }

        public virtual List<T> GetAll()
        {
            return dal.GetAll().ToList();
        }

        /// <summary>
        /// 利用反射调用方法
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="objs"></param>
        /// <returns></returns>
        public object InvokeMethod(string methodName, object[] objs)
        {
            return this.InvokeMethod(methodName, objs, null);
        }

        /// <summary>
        /// 利用反射调用方法
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="objs"></param>
        /// <param name="types"></param>
        /// <returns></returns>
        public object InvokeMethod(string methodName, object[] objs, Type[] types)
        {
            MethodInfo m;
            if (types == null)
                m = _type.GetMethod(methodName);
            else
                m = _type.GetMethod(methodName, types);
            return m.Invoke(dal, objs);
        }
        #endregion

        void IDisposable.Dispose()
        {
            // DO dispose method;
            dal = null;
            context = null;
            _type = null;
        }
    }
}
